#pragma once
#include <iostream>
#include <memory>
#include "Socket.hpp"
#include "Connection.hpp"

using namespace socket_ns;

// 统一进行listensocket管理
class Listener
{
private:
    uint16_t _port;
    std::unique_ptr<Socket> _listenSock;

public:
    Listener(uint16_t port) : _port(port), _listenSock(std::make_unique<TcpSocket>())
    {
        _listenSock->BuildTcpServerSocket(_port);
    }
    ~Listener() {}

    int ListenSockfd()
    {
        return _listenSock->Sockfd();
    }

    void Accepter(Connection *conn)
    {
        while (true)
        {
            errno = 0;
            InetAddr addr;
            int code = 0;
            int sockfd = _listenSock->Accepter(&addr, &code);
            if (sockfd > 0)
            {
                LOG(INFO, "get new link success, client: %s:%d, sockfd: %d\n",
                    addr.ip().c_str(), addr.port(), sockfd);
                conn->_R->AddConnection(sockfd, EPOLLIN | EPOLLET, NormalConnection, addr);
            }
            else
            {
                if (code == EWOULDBLOCK)
                {
                    LOG(INFO, "all link get success\n");
                    break;
                }
                else if (code == EINTR)
                {
                    continue;
                }
                else
                {
                    LOG(ERROR, "get a link failed!\n");
                    break;
                }
            }
        }
    }
};